using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;

namespace UtilZ.Dotnet.Ex.DataStruct
{
    /// <summary>
    /// 对象池
    /// </summary>
    public class ObjectPool : ObjectPoolAbs<Type>
    {
        private readonly ConcurrentDictionary<Type, SingleTypeObjectPool<object>> _typeObjectPoolDic = new ConcurrentDictionary<Type, SingleTypeObjectPool<object>>();

        /// <summary>
        /// 构造函数初始化
        /// </summary>
        public ObjectPool()
            : base()
        {

        }



        /// <summary>
        /// 添加对象集合到资源池
        /// </summary>
        /// <typeparam name="T">集合类型</typeparam>
        /// <param name="collection">复用对象集合</param>
        public void Add<T>(IEnumerable<T> collection) where T : class
        {
            if (collection == null || collection.Count() == 0)
            {
                return;
            }

            SingleTypeObjectPool<object> objectPool;
            Type type = typeof(T);
            if (!this._typeObjectPoolDic.TryGetValue(type, out objectPool))
            {
                lock (this._typeObjectPoolDic)
                {
                    if (!this._typeObjectPoolDic.TryGetValue(type, out objectPool))
                    {
                        objectPool = new SingleTypeObjectPool<object>();
                        if (!this._typeObjectPoolDic.TryAdd(type, objectPool))
                        {
                            throw new ApplicationException("添加实例失败");
                        }
                    }
                }
            }

            objectPool.Add(collection);
        }

        /// <summary>
        /// 添加对象到资源池
        /// </summary>
        /// <param name="item">复用对象</param>
        public void Add(object item)
        {
            if (item == null)
            {
                return;
            }

            Type type = item.GetType();
            SingleTypeObjectPool<object> objectPool;
            if (!this._typeObjectPoolDic.TryGetValue(type, out objectPool))
            {
                lock (this._typeObjectPoolDic)
                {
                    if (!this._typeObjectPoolDic.TryGetValue(type, out objectPool))
                    {
                        objectPool = new SingleTypeObjectPool<object>();
                        this._typeObjectPoolDic.TryAdd(type, objectPool);
                    }
                }
            }

            objectPool.Add(item);
        }





        /// <summary>
        /// 获取对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <returns>对象</returns>
        public T Take<T>() where T : class
        {
            Type type = typeof(T);
            object item;
            SingleTypeObjectPool<object> objectPool;
            if (this._typeObjectPoolDic.TryGetValue(type, out objectPool))
            {
                if (objectPool.TryTake(out item))
                {
                    return (T)item;
                }
            }

            if (base.OnRaiseTakeTimeoutResolve(type, out item))
            {
                return (T)item;
            }
            else
            {
                throw new Exception($"获取对象失败,对象池中没有对象,通过\"{nameof(TakeTimeoutResolve)}\"事件创建对象同样失败.");
            }
        }

        /// <summary>
        /// 获取对象
        /// </summary>
        /// <param name="type">对象类型</param>
        /// <returns>对象</returns>
        public object Take(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            object item;
            SingleTypeObjectPool<object> objectPool;
            if (this._typeObjectPoolDic.TryGetValue(type, out objectPool))
            {
                if (objectPool.TryTake(out item))
                {
                    return item;
                }
            }

            if (base.OnRaiseTakeTimeoutResolve(type, out item))
            {
                return item;
            }
            else
            {
                throw new Exception($"获取对象失败,对象池中没有对象,通过\"{nameof(TakeTimeoutResolve)}\"事件创建对象同样失败.");
            }
        }

        /// <summary>
        /// 尝试获取对象,获取成功返回true,获取失败返回False
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="item">对象</param>
        /// <returns>获取成功返回true,获取失败返回False</returns>
        public bool TryTake<T>(out T item) where T : class
        {
            object obj;
            if (this.TryTake(typeof(T), out obj))
            {
                item = (T)obj;
                return true;
            }
            else
            {
                item = default(T);
                return false;
            }
        }

        /// <summary>
        /// 尝试获取对象,获取成功返回true,获取失败返回False
        /// </summary>
        /// <param name="type">对象类型</param>
        /// <param name="item">对象</param>
        /// <returns>获取成功返回true,获取失败返回False</returns>
        /// <exception cref="ArgumentNullException"></exception>
        public bool TryTake(Type type, out object item)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            SingleTypeObjectPool<object> objectPool;
            if (this._typeObjectPoolDic.TryGetValue(type, out objectPool))
            {
                return objectPool.TryTake(out item);
            }
            else
            {
                if (base.OnRaiseTakeTimeoutResolve(type, out item))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }




        /// <summary>
        /// 清空集合,并返回清空项列表
        /// </summary>
        /// <returns>清空项列表</returns>
        public List<object> Clear()
        {
            List<object> list = new List<object>();
            foreach (var pool in this._typeObjectPoolDic.Values)
            {
                var tempList = pool.Clear();
                if (tempList != null)
                {
                    list.AddRange(tempList);
                }
            }
            this._typeObjectPoolDic.Clear();
            return list;
        }

        /// <summary>
        /// 清空集合,并返回清空项列表
        /// </summary>
        /// <param name="type">对象类型</param>
        /// <returns>清空项列表</returns>
        public List<object> Clear(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            SingleTypeObjectPool<object> objectPool;
            if (this._typeObjectPoolDic.TryRemove(type, out objectPool))
            {
                return objectPool.Clear().ToList();
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 移除指定项的项,如果真实项数小于了要移除的项数,则全部移除
        /// </summary>
        /// <param name="type">对象类型</param>
        /// <param name="count">要移除的项数</param>
        /// <returns>移除项列表</returns>
        public List<object> Remove(Type type, int count)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            SingleTypeObjectPool<object> objectPool;
            if (this._typeObjectPoolDic.TryGetValue(type, out objectPool))
            {
                return objectPool.Remove(count);
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 判断当前集合是否包含指定项.包含返回true,不包含返回false
        /// </summary>
        /// <param name="item">指定项</param>
        /// <returns>包含返回true,不包含返回false</returns>
        public bool Contains(object item)
        {
            if (item == null)
            {
                return false;
            }

            SingleTypeObjectPool<object> objectPool;
            if (this._typeObjectPoolDic.TryGetValue(item.GetType(), out objectPool))
            {
                return objectPool.Contains(item);
            }
            else
            {
                return false;
            }
        }




        /// <summary>
        /// 获取总项数
        /// </summary>
        public int Count()
        {
            return this._typeObjectPoolDic.Values.Sum(t => { return t.Count; });
        }

        /// <summary>
        /// 获取指定类型项数
        /// </summary>
        public int Count<T>()
        {
            return Count(typeof(T));
        }

        /// <summary>
        /// 获取指定类型项数
        /// </summary>
        public int Count(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            SingleTypeObjectPool<object> objectPool;
            if (this._typeObjectPoolDic.TryGetValue(type, out objectPool))
            {
                return objectPool.Count;
            }
            else
            {
                return 0;
            }
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            foreach (var pool in this._typeObjectPoolDic.Values)
            {
                pool.Dispose();
            }
            this._typeObjectPoolDic.Clear();
        }

    }

    /// <summary>
    /// 对象池<see cref="ObjectPool{T}"/>.
    /// </summary>
    /// <typeparam name="TypeId">对象类型标识</typeparam>
    public class ObjectPool<TypeId> : ObjectPoolAbs<TypeId>
    {
        private readonly ConcurrentDictionary<TypeId, SingleTypeObjectPool<object>> _typeObjectPoolDic = new ConcurrentDictionary<TypeId, SingleTypeObjectPool<object>>();

        /// <summary>
        /// 构造函数初始化
        /// </summary>
        public ObjectPool()
            : base()
        {

        }



        /// <summary>
        /// 添加对象集合到资源池
        /// </summary>
        /// <typeparam name="T">对象类型标识</typeparam>
        /// <param name="typeId">对象类型标识</param>
        /// <param name="collection">复用对象集合</param>
        public void Add<T>(TypeId typeId, IEnumerable<T> collection) where T : class
        {
            if (collection == null || collection.Count() == 0)
            {
                return;
            }

            if (typeId == null)
            {
                throw new ArgumentNullException(nameof(typeId));
            }

            SingleTypeObjectPool<object> objectPool;
            if (!this._typeObjectPoolDic.TryGetValue(typeId, out objectPool))
            {
                lock (this._typeObjectPoolDic)
                {
                    if (!this._typeObjectPoolDic.TryGetValue(typeId, out objectPool))
                    {
                        objectPool = new SingleTypeObjectPool<object>();
                        if (!this._typeObjectPoolDic.TryAdd(typeId, objectPool))
                        {
                            throw new ApplicationException("添加实例失败");
                        }
                    }
                }
            }

            objectPool.Add(collection);
        }

        /// <summary>
        /// 添加对象到资源池
        /// </summary>
        /// <param name="typeId">对象类型标识</param>
        /// <param name="item">复用对象</param>
        public void Add(TypeId typeId, object item)
        {
            if (item == null)
            {
                return;
            }

            if (typeId == null)
            {
                throw new ArgumentNullException(nameof(typeId));
            }

            SingleTypeObjectPool<object> objectPool;
            if (!this._typeObjectPoolDic.TryGetValue(typeId, out objectPool))
            {
                lock (this._typeObjectPoolDic)
                {
                    if (!this._typeObjectPoolDic.TryGetValue(typeId, out objectPool))
                    {
                        objectPool = new SingleTypeObjectPool<object>();
                        this._typeObjectPoolDic.TryAdd(typeId, objectPool);
                    }
                }
            }

            objectPool.Add(item);
        }





        /// <summary>
        /// 获取对象
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="typeId">对象类型标识</param>
        /// <returns>对象</returns>
        public T Take<T>(TypeId typeId) where T : class
        {
            T item;
            if (this.TryTake(typeId, out item))
            {
                return item;
            }
            else
            {
                throw new Exception($"获取对象失败,对象池中没有对象,通过\"{nameof(TakeTimeoutResolve)}\"事件创建对象同样失败.");
            }
        }

        /// <summary>
        /// 获取对象
        /// </summary>
        /// <param name="typeId">对象类型标识</param>
        /// <returns>对象</returns>
        public object Take(TypeId typeId)
        {
            object item;
            if (this.TryTake(typeId, out item))
            {
                return item;
            }
            else
            {
                throw new Exception($"获取对象失败,对象池中没有对象,通过\"{nameof(TakeTimeoutResolve)}\"事件创建对象同样失败.");
            }
        }

        /// <summary>
        /// 尝试获取对象,获取成功返回true,获取失败返回False
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="typeId">对象类型标识</param>
        /// <param name="item">对象</param>
        /// <returns>获取成功返回true,获取失败返回False</returns>
        public bool TryTake<T>(TypeId typeId, out T item) where T : class
        {
            if (typeId == null)
            {
                throw new ArgumentNullException(nameof(typeId));
            }

            object obj;
            if (this.TryTake(typeId, out obj))
            {
                item = (T)obj;
                return true;
            }
            else
            {
                item = default(T);
                return false;
            }
        }

        /// <summary>
        /// 尝试获取对象,获取成功返回true,获取失败返回False
        /// </summary>
        /// <param name="typeId">对象类型标识</param>
        /// <param name="item">对象</param>
        /// <returns>获取成功返回true,获取失败返回False</returns>
        /// <exception cref="ArgumentNullException"></exception>
        public bool TryTake(TypeId typeId, out object item)
        {
            if (typeId == null)
            {
                throw new ArgumentNullException(nameof(typeId));
            }

            SingleTypeObjectPool<object> objectPool;
            if (this._typeObjectPoolDic.TryGetValue(typeId, out objectPool))
            {
                return objectPool.TryTake(out item);
            }
            else
            {
                if (base.OnRaiseTakeTimeoutResolve(typeId, out item))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }


        /// <summary>
        /// 清空集合,并返回清空项列表
        /// </summary>
        /// <returns>清空项列表</returns>
        public List<object> Clear()
        {
            List<object> list = new List<object>();
            foreach (var pool in this._typeObjectPoolDic.Values)
            {
                var tempList = pool.Clear();
                if (tempList != null)
                {
                    list.AddRange(tempList);
                }
            }
            this._typeObjectPoolDic.Clear();
            return list;
        }

        /// <summary>
        /// 清空集合,并返回清空项列表
        /// </summary>
        /// <param name="typeId">对象类型标识</param>
        /// <returns>清空项列表</returns>
        public List<object> Clear(TypeId typeId)
        {
            if (typeId == null)
            {
                throw new ArgumentNullException(nameof(typeId));
            }

            SingleTypeObjectPool<object> objectPool;
            if (this._typeObjectPoolDic.TryRemove(typeId, out objectPool))
            {
                return objectPool.Clear().ToList();
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 移除指定项的项,如果真实项数小于了要移除的项数,则全部移除
        /// </summary>
        /// <param name="typeId">对象类型标识</param>
        /// <param name="count">要移除的项数</param>
        /// <returns>移除项列表</returns>
        public List<object> Remove(TypeId typeId, int count)
        {
            if (typeId == null)
            {
                throw new ArgumentNullException(nameof(typeId));
            }

            SingleTypeObjectPool<object> objectPool;
            if (this._typeObjectPoolDic.TryGetValue(typeId, out objectPool))
            {
                return objectPool.Remove(count);
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 判断当前集合是否包含指定项.包含返回true,不包含返回false
        /// </summary>
        /// <param name="typeId">对象类型标识</param>
        /// <param name="item">指定项</param>
        /// <returns>包含返回true,不包含返回false</returns>
        public bool Contains(TypeId typeId, object item)
        {
            if (item == null)
            {
                return false;
            }

            if (typeId == null)
            {
                throw new ArgumentNullException(nameof(typeId));
            }

            SingleTypeObjectPool<object> objectPool;
            if (this._typeObjectPoolDic.TryGetValue(typeId, out objectPool))
            {
                return objectPool.Contains(item);
            }
            else
            {
                return false;
            }
        }




        /// <summary>
        /// 获取总项数
        /// </summary>
        public int Count()
        {
            return this._typeObjectPoolDic.Values.Sum(t => { return t.Count; });
        }

        /// <summary>
        /// 获取指定类型项数
        /// </summary>
        /// <param name="typeId">对象类型标识</param>
        public int Count(TypeId typeId)
        {
            if (typeId == null)
            {
                throw new ArgumentNullException(nameof(typeId));
            }

            SingleTypeObjectPool<object> objectPool;
            if (this._typeObjectPoolDic.TryGetValue(typeId, out objectPool))
            {
                return objectPool.Count;
            }
            else
            {
                return 0;
            }
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            foreach (var pool in this._typeObjectPoolDic.Values)
            {
                pool.Dispose();
            }
            this._typeObjectPoolDic.Clear();
        }

    }







    /// <summary>
    /// 单类型对象池<see cref="SingleTypeObjectPool{T}"/>.
    /// </summary>
    /// <typeparam name="T">对象类型</typeparam>
    public class SingleTypeObjectPool<T> : ObjectPoolAbs<T>, IEnumerable<T>
        where T : class
    {
        private readonly SemaphoreSlim _semaphoreSlim;
        private readonly ConcurrentQueue<T> _items;

        /// <summary>
        /// 获取内部池
        /// </summary>
        public ConcurrentQueue<T> InnerPool
        {
            get { return _items; }
        }

        /// <summary>
        /// 获取项数
        /// </summary>
        public int Count
        {
            get { return _items.Count; }
        }




        /// <summary>
        /// 构造函数初始化
        /// </summary>
        public SingleTypeObjectPool()
            : base()
        {
            this._items = new ConcurrentQueue<T>();
            this._semaphoreSlim = new SemaphoreSlim(0);
        }

        /// <summary>
        /// 构造函数初始化
        /// </summary>
        /// <param name="collection">初始对象集合</param>
        public SingleTypeObjectPool(IEnumerable<T> collection)
            : base()
        {
            if (collection == null)
            {
                this._items = new ConcurrentQueue<T>();
                this._semaphoreSlim = new SemaphoreSlim(0);
            }

            int count = collection.Count();
            if (count == 0)
            {
                this._items = new ConcurrentQueue<T>();
                this._semaphoreSlim = new SemaphoreSlim(0);
            }
            else
            {
                this._items = new ConcurrentQueue<T>(collection);
                this._semaphoreSlim = new SemaphoreSlim(count);
            }
        }






        /// <summary>
        /// 添加对象集合到资源池
        /// </summary>
        /// <param name="collection">复用对象集合</param>
        public void Add(IEnumerable<T> collection)
        {
            if (collection == null)
            {
                return;
            }

            base.CheckDisposed();

            foreach (var item in collection)
            {
                if (item != null)
                {
                    this._items.Enqueue(item);
                    this._semaphoreSlim.Release();
                }
            }
        }

        /// <summary>
        /// 添加对象到资源池
        /// </summary>
        /// <param name="item">复用对象</param>
        public void Add(T item)
        {
            base.CheckDisposed();

            if (item != null)
            {
                this._items.Enqueue(item);
                this._semaphoreSlim.Release();
            }
        }





        /// <summary>
        /// 获取对象
        /// </summary>
        /// <returns>对象</returns>
        public T Take()
        {
            return this.Take(Timeout.Infinite, CancellationToken.None);
        }

        /// <summary>
        /// 获取对象
        /// </summary>
        /// <param name="millisecondsTimeout">超时时长,为Timeout.Infinite时无限</param>
        /// <returns>对象</returns>
        public T Take(int millisecondsTimeout)
        {
            return this.Take(millisecondsTimeout, CancellationToken.None);
        }

        /// <summary>
        /// 获取对象
        /// </summary>
        /// <param name="token">CancellationToken</param>
        /// <returns>对象</returns>
        public T Take(CancellationToken token)
        {
            return this.Take(Timeout.Infinite, token);
        }

        /// <summary>
        /// 获取对象
        /// </summary>
        /// <param name="millisecondsTimeout">超时时长,为Timeout.Infinite时无限</param>
        /// <param name="token">CancellationToken</param>
        /// <returns>对象</returns>
        public T Take(int millisecondsTimeout, CancellationToken token)
        {
            T item;
            if (this._items.TryDequeue(out item) && item != null)
            {
                return item;
            }

            while (!base._disposabled && !token.IsCancellationRequested)
            {
                try
                {
                    while (this._items.TryDequeue(out item) && item != null)
                    {
                        return item;
                    }

                    if (this._semaphoreSlim.Wait(millisecondsTimeout, token))
                    {
                        //收到信号,有两种情况:一是集合中添加了项,二是取消,重新去获取
                        continue;
                    }
                    else
                    {
                        object obj;
                        if (base.OnRaiseTakeTimeoutResolve(default(T), out obj))
                        {
                            return (T)obj;
                        }
                        else
                        {
                            throw new TimeoutException("获取对象超时，且未解决。");
                        }
                    }
                }
                catch (ObjectDisposedException)
                {
                    break;
                }
                catch (ArgumentNullException)
                {
                    //ConcurrentQueue<T>.TryTake偶尔会报ArgumentNullException异常,所以此处采用这种比较怪异的规避异常写法
                    continue;
                }
                catch (TimeoutException)
                {
                    throw;
                }
                catch (Exception)
                {
                    break;
                }
            }

            if (base._disposabled)
            {
                throw new ObjectDisposedException(this.GetType().Name, "当前对象已释放.");
            }
            else
            {
                if (token.IsCancellationRequested)
                {
                    throw new OperationCanceledException();
                }
                else
                {
                    throw new Exception("理论上不应该进入此分支.");
                }
            }
        }









        /// <summary>
        /// 尝试获取对象,获取成功返回true,获取失败返回False
        /// </summary>
        /// <param name="item">对象</param>
        /// <returns>获取成功返回true,获取失败返回False</returns>
        public bool TryTake(out T item)
        {
            while (!base._disposabled)
            {
                try
                {
                    if (this._items.TryDequeue(out item) && item != null)
                    {
                        return true;
                    }
                    else
                    {
                        break;
                    }
                }
                catch (ArgumentNullException)
                {
                    //ConcurrentQueue<T>.TryTake偶尔会报ArgumentNullException异常,所以此处采用这种比较怪异的规避异常写法
                    continue;
                }
            }

            if (base._disposabled)
            {
                item = default(T);
                return false;
            }
            else
            {
                return this.CreateItem(out item);
            }
        }

        /// <summary>
        /// 尝试获取对象,获取成功返回true,获取失败返回False
        /// </summary>
        /// <param name="millisecondsTimeout">超时时长,为Timeout.Infinite时无限</param>
        /// <param name="item">对象</param>
        /// <returns>获取成功返回true,获取失败返回False</returns>
        public bool TryTake(int millisecondsTimeout, out T item)
        {
            return this.TryTake(millisecondsTimeout, CancellationToken.None, out item);
        }

        /// <summary>
        /// 尝试获取对象,获取成功返回true,获取失败返回False
        /// </summary>
        /// <param name="token">取消CancellationToken</param>
        /// <param name="item">对象</param>
        /// <returns>获取成功返回true,获取失败返回False</returns>
        public bool TryTake(CancellationToken token, out T item)
        {
            return this.TryTake(Timeout.Infinite, token, out item);
        }

        /// <summary>
        /// 尝试获取对象,获取成功返回true,获取失败返回False
        /// </summary>
        /// <param name="millisecondsTimeout">超时时长,为Timeout.Infinite时无限</param>
        /// <param name="token">取消CancellationToken</param>
        /// <param name="item">对象</param>
        /// <returns>获取成功返回true,获取失败返回False</returns>
        public bool TryTake(int millisecondsTimeout, CancellationToken token, out T item)
        {
            if (this._items.TryDequeue(out item) && item != null)
            {
                return true;
            }

            while (!base._disposabled && !token.IsCancellationRequested)
            {
                try
                {
                    while (this._items.TryDequeue(out item) && item != null)
                    {
                        return true;
                    }

                    if (this._semaphoreSlim.Wait(millisecondsTimeout, token))
                    {
                        //收到信号,有两种情况:一是集合中添加了项,二是取消,重新去获取
                        continue;
                    }
                    else
                    {
                        //超时,结束循环
                        object obj;
                        if (base.OnRaiseTakeTimeoutResolve(default(T), out obj))
                        {
                            item = (T)obj;
                            return true;
                        }
                        else
                        {
                            throw new TimeoutException("获取对象超时，且未解决。");
                        }
                    }
                }
                catch (ObjectDisposedException)
                {
                    break;
                }
                catch (ArgumentNullException)
                {
                    //ConcurrentQueue<T>.TryTake偶尔会报ArgumentNullException异常,所以此处采用这种比较怪异的规避异常写法
                    continue;
                }
                catch (Exception)
                {
                    break;
                }
            }

            if (base._disposabled || token.IsCancellationRequested)
            {
                item = default(T);
                return false;
            }
            else
            {
                return this.CreateItem(out item);
            }
        }




#if !NET4_0
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
        private bool CreateItem(out T item)
        {
            object obj;
            if (base.OnRaiseTakeTimeoutResolve(default(T), out obj))
            {
                item = (T)obj;
                return true;
            }
            else
            {
                item = default(T);
                return false;
            }
        }






        /// <summary>
        /// 移除指定项的项,如果真实项数小于了要移除的项数,则全部移除
        /// </summary>
        /// <param name="count">要移除的项数</param>
        /// <returns>移除项列表</returns>
        public List<T> Remove(int count)
        {
            if (count <= 0)
            {
                return null;
            }

            List<T> list = null;
            T item;

            while (true)
            {
                if (this.TryTake(out item))
                {
                    if (list == null)
                    {
                        list = new List<T>();
                    }

                    list.Add(item);
                    if (list.Count >= count)
                    {
                        break;
                    }
                }
                else
                {
                    break;
                }
            }

            return list;
        }

        /// <summary>
        /// 清空集合,并返回清空项列表
        /// </summary>
        /// <returns>清空项列表</returns>
        public List<T> Clear()
        {
            List<T> list = null;
            T item;

            while (true)
            {
                try
                {
                    if (this.TryTake(out item))
                    {
                        if (list == null)
                        {
                            list = new List<T>();
                        }

                        list.Add(item);
                    }
                    else
                    {
                        break;
                    }
                }
                catch (ArgumentNullException)
                {
                    continue;
                }
            }

            return list;
        }

        /// <summary>
        /// 判断当前集合是否包含指定项.包含返回true,不包含返回false
        /// </summary>
        /// <param name="item">指定项</param>
        /// <returns>包含返回true,不包含返回false</returns>
        public bool Contains(T item)
        {
            if (item == null)
            {
                return false;
            }

            return this._items.Contains(item);
        }




        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public IEnumerator<T> GetEnumerator()
        {
            return this._items.GetEnumerator();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return this._items.GetEnumerator();
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            this._semaphoreSlim.Dispose();
        }

    }




    /// <summary>
    /// 对象池基类<see cref="ObjectPoolAbs{TypeId}"/>.
    /// </summary>
    /// <typeparam name="TypeId">对象类型标识</typeparam>
    public abstract class ObjectPoolAbs<TypeId> : IDisposable
    {
        /// <summary>
        /// 对象不存在解决事件
        /// </summary>
        private event EventHandler<ObjectPoolResolveEventArgs<TypeId>> _takeTimeoutResolve = null;
        /// <summary>
        /// 对象不存在解决事件
        /// </summary>
        public event EventHandler<ObjectPoolResolveEventArgs<TypeId>> TakeTimeoutResolve
        {
            add
            {
                _takeTimeoutResolve += value;
            }
            remove
            {
                _takeTimeoutResolve -= value;
            }
        }


        /// <summary>
        /// 构造函数
        /// </summary>
        public ObjectPoolAbs()
        {

        }


        /// <summary>
        /// 触发尝试解决对象不存在事件,创建成功返回true,失败返回false
        /// </summary>
        /// <param name="typeId">对象类型标识</param>
        /// <param name="result">创建成功的对象实例</param>
        /// <returns>创建成功返回true,失败返回false</returns>
        protected bool OnRaiseTakeTimeoutResolve(TypeId typeId, out object result)
        {
            result = null;
            var handler = this._takeTimeoutResolve;
            if (handler == null)
            {
                //throw new Exception($"获取对象失败,对象池中没有对象,也未注册\"{nameof(ObjectResolve)}\"事件以创建对象.");
                return false;
            }

            var args = new ObjectPoolResolveEventArgs<TypeId>(typeId);
            handler(this, args);
            if (args.Value != null)
            {
                result = args.Value;
                return true;
            }
            else
            {
                return false;
                //throw new Exception($"获取对象失败,对象池中没有对象,通过注册\"{nameof(ObjectResolve)}\"事件创建对象失败.");
            }
        }


        /// <summary>
        /// 当前对象是否是释放标识
        /// </summary>
        /// <returns></returns>
        protected bool _disposabled = false;

        /// <summary>
        /// 检查当前对象是否已释放
        /// </summary>
        /// <exception cref="ObjectDisposedException"></exception>
        protected void CheckDisposed()
        {
            if (this._disposabled)
            {
                throw new ObjectDisposedException(this.GetType().Name, "当前对象已释放.");
            }
        }

        /// <summary>
        /// Dispose
        /// </summary>
        public void Dispose()
        {
            if (this._disposabled)
            {
                return;
            }

            this._disposabled = true;
            this.Dispose(true);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="disposing"></param>
        protected virtual void Dispose(bool disposing)
        {

        }

    }

    /// <summary>
    /// 对象不存在解决方法事件参数<see cref="ObjectPoolResolveEventArgs{T}"/>.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ObjectPoolResolveEventArgs<T> : EventArgs
    {
        /// <summary>
        /// 对象类型标识
        /// </summary>
        public T TypeId { get; private set; }

        /// <summary>
        /// 解决的对象
        /// </summary>
        public object Value { get; set; } = null;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="typeId">对象类型标识</param>
        public ObjectPoolResolveEventArgs(T typeId)
        {
            this.TypeId = typeId;
        }

    }

    /// <summary>
    /// 创建对象策略
    /// </summary>
    /// <typeparam name="TypeId">对象类型</typeparam>
    /// <typeparam name="TObjectType">创建成功的对象</typeparam>
    public interface IObjectCreatePolicy<TypeId, TObjectType> where TObjectType : class
    {
        /// <summary>
        /// 尝试创建一个对象,创建成功返回true,失败返回false
        /// </summary>
        /// <param name="typeId">对象类型</param>
        /// <param name="obj">创建成功的对象</param>
        /// <returns>创建成功返回true,失败返回false</returns>
        bool TryCreate(TypeId typeId, out TObjectType obj);
    }
}
